﻿// Solution: HW
// Project: HW.Controls
// FileName: HighlightStyle.cs
// Created: 2015.07.14 20:51
// Last format: 2015.07.15 8:55
// UserName: kp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;

namespace System.Controls.Highliter
{
  public class HighlightStyle : ICloneable
  {
    #region ... constructors...

    private const string DEFAULT_FONT_NAME = "Courier New";
    private const double DEFAULT_FONT_SIZE = 14;

    private static readonly Color _default_Foreground = Colors.Black;
    private static readonly Color _default_Background = Color.FromRgb( 220, 220, 185 );

    static HighlightStyle()
    {
      _default = new HighlightStyle()
                  {
                    FontSize = DEFAULT_FONT_SIZE,
                    FontName = DEFAULT_FONT_NAME,
                    Background = _default_Background,
                    Foreground = _default_Foreground,
                    FontStyle = FontStyles.Normal,
                    FontWeight = FontWeights.Normal,
                  };
    }

    private static Color FromBrush( Brush brush, Color defColor )
    {
      if ( brush == null )
        return defColor;

      var solid = brush as SolidColorBrush;
      if ( solid != null )
        return solid.Color;

      var gradient = brush as GradientBrush;
      if ( gradient == null )
        return defColor;

      var r = 0;
      var g = 0;
      var b = 0;

      foreach ( var gradient_stop in gradient.GradientStops )
      {
        r += gradient_stop.Color.R;
        g += gradient_stop.Color.G;
        b += gradient_stop.Color.B;
      }

      r /= gradient.GradientStops.Count;
      g /= gradient.GradientStops.Count;
      b /= gradient.GradientStops.Count;

      return Color.FromRgb( (byte) r, (byte) g, (byte) b );
    }

    public static void SetDefaults( string fontName = null, double? fontSize = null, FontStyle? fontStyle = null, FontWeight? fontWeight = null, Brush background = null, Brush foreground = null )
    {
      var fore = FromBrush( foreground, _default_Foreground );
      var back = FromBrush( background, _default_Background );

      SetDefaults( fontName, fontSize, fontStyle, fontWeight, back, fore );
    }

    public static void SetDefaults( string fontName = null, double? fontSize = null, FontStyle? fontStyle = null, FontWeight? fontWeight = null, Color? background = null, Color? foreground = null )
    {
      _default.FontName = !string.IsNullOrEmpty( fontName ) ? fontName : DEFAULT_FONT_NAME;
      _default.FontSize = fontSize ?? DEFAULT_FONT_SIZE;
      _default.Background = background ?? _default_Background;
      _default.Foreground = foreground ?? _default_Foreground;
      _default.FontStyle = fontStyle ?? FontStyles.Normal;
      _default.FontWeight = fontWeight ?? FontWeights.Normal;
    }

    #endregion

    #region ... properties indexers ...

    public double FontSize
    {
      get { return fFontSize ?? _default.FontSize; }
      set { fFontSize = value; }
    }

    public string FontName
    {
      get { return string.IsNullOrEmpty( fFontName ) ? _default.FontName : fFontName; }
      set { fFontName = value; }
    }

    public Color Foreground
    {
      get { return fForegound ?? _default.Foreground; }
      set { fForegound = value; }
    }

    public Brush ForegroundBrush
    {
      get { return new SolidColorBrush( Foreground ); }
    }

    public Color Background
    {
      get { return fBackground ?? _default.Background; }
      set { fBackground = value; }
    }

    public Brush BackgroundBrush
    {
      get { return new SolidColorBrush( Background ); }
    }

    public FontWeight FontWeight
    {
      get { return fFontWeight ?? _default.FontWeight; }
      set { fFontWeight = value; }
    }

    public FontStyle FontStyle
    {
      get { return fFontStyle ?? _default.FontStyle; }
      set { fFontStyle = value; }
    }

    #endregion

    #region ... interface implementations ...

    #region Implementation of ICloneable

    object ICloneable.Clone()
    {
      return Clone();
    }

    #endregion

    #endregion

    #region ...public methods...


    public static HighlightStyle GetDefault()
    {
      return _default;
    }

    public HighlightStyle Clone()
    {
      return new HighlightStyle()
             {
               FontSize = FontSize,
               FontName = FontName,
               Foreground = Foreground,
               Background = Background,
               FontWeight = FontWeight,
               FontStyle = FontStyle
             };
    }

    #endregion

    private static readonly HighlightStyle _default;

    #region ... fields ...

    private Color? fBackground;
    private string fFontName;
    private double? fFontSize;
    private FontStyle? fFontStyle;
    private FontWeight? fFontWeight;
    private Color? fForegound;

    #endregion
  }
}
